#ifndef MEDIAPLAYER_OPTIONS_H
#define MEDIAPLAYER_OPTIONS_H

typedef struct PlayerOptions {

    const AVClass *av_class;

    AVDictionary *opts;

    int loop;
    int infinite_buffer;
    int framedrop;
    int start_time;
    int start_on_prepared;
    int pictq_size;
    int audioframe_size;
    int max_buffer_size;
    int max_buffer_duration;
    int min_buffer_size;//unuse
    int min_buffer_duration;//ms
    int min_audio_pkt;
    int max_audio_pkt;

    int audio_out_sample_rate;
    int audio_out_format;
    int audio_out_channel_layout;

    int keep_video_ratio;

}PlayerOptions;

#define OPTION_OFFSET(x) offsetof(PlayerOptions, x)
#define OPTION_INT(default__, min__, max__) \
    .type = AV_OPT_TYPE_INT, \
    { .i64 = default__ }, \
    .min = min__, \
    .max = max__, \
    .flags = AV_OPT_FLAG_DECODING_PARAM
#define OPTION_INT64(default__, min__, max__) \
    .type = AV_OPT_TYPE_INT64, \
    { .i64 = default__ }, \
    .min = min__, \
    .max = max__, \
    .flags = AV_OPT_FLAG_DECODING_PARAM
#define OPTION_DOUBLE(default__, min__, max__) \
    .type = AV_OPT_TYPE_DOUBLE, \
    { .dbl = default__ }, \
    .min = min__, \
    .max = max__, \
    .flags = AV_OPT_FLAG_DECODING_PARAM
#define OPTION_CONST(default__) \
    .type = AV_OPT_TYPE_CONST, \
    { .i64 = default__ }, \
    .min = INT_MIN, \
    .max = INT_MAX, \
    .flags = AV_OPT_FLAG_DECODING_PARAM

#define OPTION_STR(default__) \
    .type = AV_OPT_TYPE_STRING, \
    { .str = default__ }, \
    .min = 0, \
    .max = 0, \
    .flags = AV_OPT_FLAG_DECODING_PARAM

#define MAX_QUEUE_SIZE (15 * 1024 * 1024) //15M
#define MIN_PACKET_DURATION 100  //ms unuse
#define MAX_PACKET_DURATION 500 //ms unuse

static const AVOption player_context_options[] = {
    { "loop",                           "set number of times the playback shall be looped",
        OPTION_OFFSET(loop),            OPTION_INT(1, INT_MIN, INT_MAX) },

    { "infbuf",                         "don't limit the input buffer size (useful with realtime streams)",
        OPTION_OFFSET(infinite_buffer), OPTION_INT(0, 0, 1) },

    { "framedrop",                      "drop frames when cpu is too slow",
        OPTION_OFFSET(framedrop),       OPTION_INT(0, -1, 120) },

    { "seek-at-start",                  "set offset of player should be seeked",
        OPTION_OFFSET(start_time),       OPTION_INT64(0, 0, INT_MAX) },

    { "start-on-prepared",                  "automatically start playing on prepared",
        OPTION_OFFSET(start_on_prepared),   OPTION_INT(1, 0, 1) },

    //控制解码后的视频AVFrame数量
    { "video-pictq-size",                   "max picture queue frame count",
        OPTION_OFFSET(pictq_size),          OPTION_INT(3, 3, 16) },

    //控制解码后的音频AVFrame数量
    { "audio-frame-size",                   "max audio frame count",
        OPTION_OFFSET(audioframe_size),          OPTION_INT(3, 3, 16) },

    //解封装后音视频packet队列最大值
    { "max-buffer-size",                   "max packet buffer size",
        OPTION_OFFSET(max_buffer_size),          OPTION_INT(MAX_QUEUE_SIZE, 0, MAX_QUEUE_SIZE) },

    //解封装后音视频最大缓冲时间 ms
    { "max-buffer-duration",                   "max packet buffer duration(ms)",
        OPTION_OFFSET(max_buffer_duration),          OPTION_INT(200, MIN_PACKET_DURATION, INT_MAX) },

    //解封装后音视频packet队列最小值 unused
    { "min-buffer-size",                   "min packet buffer size",
        OPTION_OFFSET(min_buffer_size),          OPTION_INT(0, 0, 0) },

    //解封装后音视频最小缓冲时间,unused
    { "min-buffer-duration",                   "min packet buffer duration(ms)",
        OPTION_OFFSET(min_buffer_duration),          OPTION_INT(200, MIN_PACKET_DURATION, INT_MAX) },

    //解封装后音频最少帧数
    { "min-audio-packet",                   "min audio packet",
        OPTION_OFFSET(min_audio_pkt),          OPTION_INT(30, INT_MIN, INT_MAX) },

    //解封装后音频最大帧数
    { "max-audio-packet",                   "max audio packet",
        OPTION_OFFSET(max_audio_pkt),          OPTION_INT(40, INT_MIN, INT_MAX) },

    //音频重采样参数
    { "audio-out-sample-rate",                   "audio out sample rate",
        OPTION_OFFSET(audio_out_sample_rate),          OPTION_INT(44100, INT_MIN, INT_MAX) },

    //音频重采样参数
    { "audio-out-format",                   "audio out sample rate",
        OPTION_OFFSET(audio_out_format),          OPTION_INT(AV_SAMPLE_FMT_S16, INT_MIN, INT_MAX) },

    //音频重采样参数
    { "audio-out-channel-layout",                   "audio out sample rate",
        OPTION_OFFSET(audio_out_channel_layout),          OPTION_INT(AV_CH_LAYOUT_STEREO, INT_MIN, INT_MAX) },

    { "keep-video-ratio",                  "When enabled, scaling will respect original aspect ratio",
        OPTION_OFFSET(keep_video_ratio),   OPTION_INT(0, 0, 1) },

    { NULL }
};

const AVClass player_context_class = {
    .class_name       = "MediaPlayer",
    .item_name        = NULL,
    .option           = player_context_options,
    .version          = LIBAVUTIL_VERSION_INT,
    .log_level_offset_offset = 0,
    .parent_log_context_offset = 0,
    .child_next       = NULL,
    .child_class_next = NULL,
};

#undef OPTION_STR
#undef OPTION_CONST
#undef OPTION_INT
#undef OPTION_OFFSET

#endif
